home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
LIBRARY
/
PAS_0693
/
DSWRITE.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-06-30
|
4KB
|
115 lines
{─ Fido Pascal Conference ────────────────────────────────────────────── PASCAL ─
Msg : 300 of 319
From : Sean Palmer 1:104/123.0 22 Jun 93 23:10
To : Lou Duchez
Subj : Fast Direct Writes
────────────────────────────────────────────────────────────────────────────────
LD>SP>I've optimized it a little, if you're interested... 8)
LD>SP>procedure qwrite(x, y: byte; s: string; f, b: byte);
LD>Interesting optimizations -- do I assume that Inc, Dec, Pred, and Succ
LD>are faster than I had ever imagined? (Shoot, I always figured they'd be
LD>a lot slower than normal arithmetic!) Thanks!
Succ and Pred are faster for byte-sized ordinals (at least in TP 6.0)
than +1 and -1. The same for word-size. See, with +1 and -1, the byte
gets converted into a word first, but with Succ() and Pred() it
stays a byte... Inc(I) is faster than I:=I+1 or I:=Succ(I) stuff in 6.0
but I think 7.0+ optimize them all to the same code...not sure, I don't
have 7.0...8(
Actually the fastest part of what I did is to pre-calculate the
attribute as the hi byte of a word, and use word stores instead of byte
stores. Could be done alot faster in assembly (don't access any
memory-based variables that way, it's all in registers..8)
Here is a direct screen write unit I wrote in BASM. VERY fast...}
{$A-,B-,D-,E-,F-,G-,I-,L-,N-,O-,R-,S-,V-,X+}
unit dswrite;
interface
const
vSeg:word=$B800; {change for mono}
{in following parms, s=source,d=destination,n=count, words are offsets
into video memory (you calculate them with ((y*80+x)*2)}
{I did this mainly so less parms would have to be sent, as TP does a
good job of the arithmetic for that expression...Oh well if you really
don't like it I could make these use x and y coords, but this was
basically chopped from another project of mine..}
procedure moveScr(s,d,n:word); {one part of screen to another}
procedure toScr(var s;d,n:word); {from string to video ram}
procedure toScrA(var s;d,n:word;a:byte); {ditto with attribute also}
procedure fillScr(d,n:word;c:char); {mainly useful for rows}
procedure fillAttr(d,n:word;a:byte); {ditto}
implementation
procedure moveScr(s,d,n:word);assembler;asm
mov cx,n; jcxz @X;
push ds; mov ax,vSeg; mov es,ax; mov ds,ax;
mov si,s; shl si,1;
mov di,d; shl di,1;
cmp si,di; jb @REV; {move in reverse to prevent overwrite}
cld; jmp @GO;
@REV: std; shl cx,1; add si,cx; add di,cx; shr cx,1; {start at end}
@GO: repz movsw; {move attr too!}
pop ds;
@X:
end;
procedure toScr(var s;d,n:word);assembler;asm
mov cx,n; jcxz @X;
push ds; mov es,vSeg;
mov di,d; shl di,1;
lds si,s; cld;
@L: movsb; inc di; loop @L;
pop ds;
@X:
end;
procedure toScrA(var s;d,n:word;a:byte);assembler;asm
mov cx,n; jcxz @X;
push ds; mov es,vSeg;
mov di,d; shl di,1;
lds si,s; cld;
mov al,a; {attribute}
@L: movsb; {doesn't affect al reg}
stosb; loop @L;
pop ds;
@X:
end;
procedure fillScr(d,n:word;c:char);assembler;asm
mov cx,n; jcxz @X;
mov es,vSeg;
mov di,d; shl di,1;
mov al,c; cld;
@L: stosb; inc di; loop @L;
@X:
end;
procedure fillAttr(d,n:word;a:byte);assembler;asm
mov cx,n; jcxz @X;
mov es,vSeg;
mov di,d; shl di,1;
mov al,a; cld;
@L: inc di; stosb; loop @L;
@X:
end;
end.
Keep in mind these are VERY low-level and aren't necessarily gonna be
easy to work with but they are, by god, FAST.
LD>As to why I pass attributes and don't use WhereX() and WhereY(), I wrote
LD>QWRITE mostly for screen drawing -- in fact, QWRITE doesn't even move the
LD>cursor. It's no good for "scrolling" text, but goldang, when you want
LD>to draw a box on the screen or fill a region with a given character ...
These don't either (cursor? who needs it!)
QWrite'll work a little faster now, anyway...